﻿using DotPowerJob.Models;
using DotPowerJob.Responses;
using Flurl;
using Flurl.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DotPowerJob.Hosted
{
    /// <summary>
    /// 定时获取真正的调度服务地址
    /// </summary>
    public class JobDiscoveryService : BackgroundService
    {
        private readonly ILogger _logger;
        private readonly PowerJobConfig _powerJobConfig;
        public JobDiscoveryService(
            ILogger<JobDiscoveryService> logger,
            IOptions<PowerJobConfig> options)
        {
            this._logger = logger;
            if (options == null)
                throw new ArgumentNullException(nameof(options));
            _powerJobConfig = options.Value;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    var result = await _powerJobConfig.ServiceAddresses
                        .AppendPathSegment("server/acquire")
                        .SetQueryParam("appId", PowerJobCache.AppId)
                        .SetQueryParam("protocol", this._powerJobConfig.Protocol)
                        .GetJsonAsync<AcquireResponse>();
                    if (result != null && result.Success)
                    {
                        PowerJobCache.ServerAddress =
                            result.Data.StartsWith("http", StringComparison.OrdinalIgnoreCase) ? result.Data : $"http://{result.Data}";
                    }
                    else
                    {
                        this._logger.LogInformation("DiscoveryService Request Faild");
                    }
                    await Task.Delay(TimeSpan.FromSeconds(20), stoppingToken);
                }
                catch (TaskCanceledException)
                {
                    this._logger.LogInformation("--- Application stopping ---");
                }
                catch (Exception ex)
                {
                    await Task.Delay(TimeSpan.FromSeconds(20), stoppingToken);
                    this._logger.LogError(ex, "DiscoveryService error:{0}", ex.Message);
                }
            }
        }
    }
}
